#ifndef IXP_GRAPH
#define IXP_GRAPH 
#include "define.h"
using namespace std;


class ixp_graph{


/************************************************************************************************
 |                                                                                              |
 |                                                                                              |
 |                                              Tipi                                            |
 |                                                                                              |
 |                                                                                              |
 ************************************************************************************************/
 
 	/***
 	 *	informazioni che descrivono ogni IXP
 	 ***/
 	struct info_ixp {
 	
 		/* nome corto */
 		string short_name;
 		/* nome lungo */
 		string long_name;
 		
 		/* continente */
 		string continent;
 		/* nazione */
 		string nation;
 		/* citta' */
 		string city;
 	
 	};
 	
 
 	/***
 	 *	metriche che descivono le proprieta' di un sottografo indotto su un ixp
 	 ***/
 	struct metriche_ixp {
 		
 		/* numero totale dei membri, compresi asn privati */
 		unsigned int tot_members;
 		/* numero di membri con asn pubblico */
 		unsigned int public_members;
 		/* numero di membri con asn pubblico e che hanno stabilito almeno un peering presso l'ixp */
 		unsigned int peering_members;
 		
 		/* numero di peering */
 		unsigned int peering;
 		/* numero di connessioni verso il resto del grafo di Internet */
 		unsigned int edges_cut;
 		
 		/* degree medio */
 		float avg_degree;
 		/* degree massimo: 
 			first = valore, second = lista ASN che hanno max degree */
 		pair < unsigned int, set<unsigned int> > max_degree;
 		/* rapporto fra degree massimo osservato e degree massimo osservabile */
 		float hub_dominance;
 		/* somma dei degree di ciascun nodo */
 		unsigned int volume;
 		
 		/* clustering coefficient medio */ 		
 		float avg_clustering;
 		/* rapporto fra numero di link effettivi e link possibili fra membri pubblici */
 		float link_density;
 		/* link density moltiplicata per il numero di membri */
 		float scaled_link_density;
 		/* metrica complementare alla link density */
 		float internal_density;
 		
 		/* shortest path length media */
 		float avg_shortest_path_length;
 		/* shortest path length massima */
 		unsigned int diameter;
 		
 		/* out degree fraction del sottografo indotto */
 		float odf;
 		/* conductance */
 		float conductance;
 		/* minima odf fra le odf di ciascun membro */
 		float min_odf;
 		/* massima odf fra le odf di ciascun membro */
 		float max_odf;
 		/* odf media fra le odf di ciascun membro */
 		float avg_odf;
 		/* odf di ogni nodo: 
 			key = asn del nodo, value = odf del nodo */
 		map < unsigned int, float > node_odf;
 		/* frazione di nodi che sono piu' connessi verso l'esterno */
 		float flake_odf;
 		
 		/* rapporto fra numero effettivo di connessioni verso l'esterno e massimo possibile */
 		float cut_ratio;
 		/* normalized cut */
 		float norm_cut;
 		
 		/* numero medio di link per nodo che puntano all'esterno */
 		float expansion;
 		
 		/* shell index medio */
 		float avg_shell_index;
 		/* shell index massimo */
 		unsigned int max_shell_index;
 		/* shell index minimo */
 		unsigned int min_shell_index;
 		/* funzione di massa di probabilita' (probability mass function) dello shell index: 
 			key = valore di shell index, value = frazione di nodi con tale valore */
 		map < unsigned int, float > shell_index_pmf;
 		/* compementary cumulative distribution function (CCDF) dello shell index:
 			key = valore di shell index, 
 			value = probabilita' che lo shell index sia maggiore del valore specificato in key */
 		map < unsigned int, float > shell_index_ccdf;
 		/*  funzione di massa di probabilita' del degree:
 			key = valore del degree, 
 			value = probabilita' del valore */
 		map < unsigned int, float > degree_pmf;
 		/*  compementary cumulative distribution function (CCDF) del degree:
 			key = valore del degree, 
 			value = probabilita' che il degree sia maggiore del valore specificato in key  */
 		map < unsigned int, float > degree_ccdf;
 		/* embeddedness minima */
 		float min_embed;
 		/* embeddedness massima */
 		float max_embed;
 		/* embeddedness media */
 		float avg_embed;
 		/* embeddedness di ogni nodo: 
 			key = asn del nodo, value = embeddedness del nodo */
 		map < unsigned int, float > node_embed;
 		
 	};
 	
 	/***
 	 *	metriche relative ad ogni Autonomous System (con ASN pubblico) incontrato
 	 ***/
 	struct metriche_as {
 	    /* indica a quanti ixp appartiene l'ASN */
 	    unsigned int member_presence;
 	    /* indica quanti peering effettua l'ASN negli IXP a cui partecipa */
 	    unsigned int member_connectivity;
 	    /* numero di connessioni dell'AS in Internet */
 	    int global_degree;
 	};
 	
 	/***
 	 *	metriche aggregate (valori medi) su un insieme di IXP
 	 *	(se qualche valore e' NaN significa che tutti gli IXP dell'insieme avevano NaN come valore 
 	 *		della metrica in questione)
 	 ***/
 	struct metriche_agg {
 		
 		/* numero di IXP a cui si riferiscono le metriche */
 		unsigned int num_ixp;
 		
 		/* numero totale dei membri, compresi asn privati */
 		float tot_members;
 		/* numero di membri con asn pubblico */
 		float public_members;
 		/* numero di membri con asn pubblico e che hanno stabilito almeno un peering presso l'ixp */
 		float peering_members;
 		
 		/* numero di peering */
 		float peering;
 		/* numero di connessioni verso il resto del grafo di Internet */
 		float edges_cut;
 		
 		/* degree medio */
 		float avg_degree;
 		/* degree massimo: 
 			first = valore, 
 			second = ASN che compaiono con max degree (key) e numero di volte che compaiono (value) */
 		pair < float, map < unsigned int, unsigned int > > max_degree;
 		/* rapporto fra degree massimo osservato e degree massimo osservabile: 
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (accade per gli IXP formati da solo 1 nodo) */
 		pair < float, unsigned int > hub_dominance;
 		/* somma dei degree di ciascun nodo */
 		float volume;
 		
 		/* clustering coefficient medio: 
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (accade per gli IXP formati da solo nodi che hanno 
 													meno di 2 neighbor, cioe' se max_degree < 2) */		
 		pair < float, unsigned int > avg_clustering;
 		/* rapporto fra numero di link effettivi e link possibili fra membri pubblici:
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (accade per gli IXP formati da solo 1 nodo) */
 		pair < float, unsigned int > link_density;
 		/* funzione di massa di probabilita' della link density: 
 			key = valore di link density, 
 			value = probabilita' del valore (frazione di IXP con tale valore) */
 		map < float, float > link_density_pmf;
 		/* CCDF della link density: 
 			key = valore di link density, 
 			value = frazione di IXP con link density maggiore del valore indicato da key */
 		map < float, float > link_density_ccdf;
 		/* link density moltiplicata per il numero di membri:
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (accade per gli IXP formati da solo 1 nodo) */
 		pair < float, unsigned int > scaled_link_density;
 		/* metrica complementare alla link density:
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (accade per gli IXP formati da solo 1 nodo) */
 		pair < float, unsigned int > internal_density;
 		
 		/* shortest path length media:
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (IXP formati da solo nodi sconnessi) */
 		pair < float, unsigned int > avg_shortest_path_length;
 		/* shortest path length massima
 			first = valore medio, 
 			second = numero di IXP che hanno 0 (IXP formati da solo nodi sconnessi) */
 		pair < float, unsigned int > diameter;
 		
 		/* out degree fraction dei sottografi indotti: 
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (IXP formati da solo nodi sconnessi in Internet) */
 		pair < float, unsigned int > odf;
 		/* conductance:
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (IXP formati da solo nodi sconnessi in Internet) */
 		pair < float, unsigned int > conductance;
 		/* minima odf fra le odf di ciascun membro:
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (IXP formati da solo nodi sconnessi in Internet) */
 		pair < float, unsigned int > min_odf;
 		/* massima odf fra le odf di ciascun membro:
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (IXP formati da solo nodi sconnessi in Internet) */
 		pair < float, unsigned int > max_odf;
 		/* odf media fra le odf di ciascun membro:
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (IXP formati da solo nodi sconnessi in Internet) */
 		pair < float, unsigned int > avg_odf;
 		/* frazione di nodi che sono piu' connessi verso l'esterno:
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (IXP formati da solo nodi sconnessi in Internet) */
 		pair < float, unsigned int > flake_odf;
 		
 		/* rapporto fra numero effettivo di connessioni verso l'esterno e massimo possibile:
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (IXP con nessun membro pubblico oppure se tutti i 
 													nodi del grafo di Internet sono membri dell'IXP) */
 		pair < float, unsigned int > cut_ratio;
 		/* normalized cut:
 			first = valore medio, 
 			second = numero di IXP che hanno NaN */
 		pair < float, unsigned int > norm_cut;
 		
 		/* numero medio di link per nodo che puntano all'esterno */
 		float expansion;
 		
 		/* shell index medio */
 		float avg_shell_index;
 		/* shell index massimo */
 		float max_shell_index;
 		/* shell index minimo */
 		float min_shell_index;
 		/* funzione di massa di probabilita' dello shell index: 
 			key = valore di shell index, value = probabilita' del valore */
 		map < unsigned int, float > shell_index_pmf;
 		/* compementary cumulative distribution function (CCDF) dello shell index:
 			key = valore di shell index, 
 			value = probabilita' che lo shell index sia maggiore del valore specificato in key */
 		map < unsigned int, float > shell_index_ccdf;
 		
 		
 		/* embeddedness minima:
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (IXP formati da solo nodi sconnessi in Internet) */
 		pair < float, unsigned int > min_embed;
 		/* embeddedness massima:
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (IXP formati da solo nodi sconnessi in Internet) */
 		pair < float, unsigned int > max_embed;
 		/* embeddedness media:
 			first = valore medio, 
 			second = numero di IXP che hanno NaN (IXP formati da solo nodi sconnessi in Internet) */
 		pair < float, unsigned int > avg_embed;
 		
 	};
 	    

/************************************************************************************************
 |                                                                                              |
 |                                                                                              |
 |                                           Variabili                                          |
 |                                                                                              |
 |                                                                                              |
 ************************************************************************************************/
	
	/***
	*	grafo globale di Internet
	*	pair <ASN,ASN>
	***/
	set <pair <unsigned int,unsigned int> > global;
	
	/***
	*	grafo globale di Internet togliendo i route server dai sottografi
	*	pair <ASN,ASN>
	***/
	set <pair <unsigned int,unsigned int> > global_nrs;
	
	/***
	 *	grafo globale di Internet togliendo i route server dai sottografi e costruendo una clique fra 
	 *	peer dei route server
	 *	pair <ASN,ASN>
	***/
	set <pair <unsigned int,unsigned int> > global_nrs_clique;
	
	/***
	 *	mapping fra ASN e node_id del grafo igraph di Internet
	 ***/
	map <unsigned int, unsigned int> global_mapping;
	
	/***
	 *	mapping fra ASN e node_id del grafo igraph di Internet togliendo i route server dai sottografi
	 ***/
	map <unsigned int, unsigned int> global_mapping_nrs;
	
	/***
	 *	mapping fra ASN e node_id del grafo igraph di Internet togliendo i route server dai sottografi 
	 *	e costruendo una clique fra i peer dei route server
	 ***/
	map <unsigned int, unsigned int> global_mapping_nrs_clique;
	
	/***
	*	grafo globale di internet
	***/
	igraph_t global_graph;
	
	/***
	 *	grafo globale di internet togliendo i route server dai sottografi
	 ***/
	igraph_t global_graph_nrs;
	
	/***
	 *	grafo globale di internet togliendo i route server dai sottografi e costruendo una clique fra 
	 *	peer dei route server
	 ***/
	igraph_t global_graph_nrs_clique;
	
	/***
	*	Link relativi ad ogni IXP
	*	chiave => IXP_ID
	*	pair <ASN,ASN> 
	***/
	map <int, set <pair <unsigned int,unsigned int> > > link_indotti;
	
	/***
    *	Nodi
	*	contiene mapping tra AS_NUMBER e nodi di igraph:
	*	chiave => IXP_ID
	*	submap <ASN (key), nodo_igraph> 
	***/
	map <int, map <unsigned int, unsigned int> > nodi_indotti;
    
    /***
	*	Link relativi ad ogni IXP senza route server
	*	chiave => IXP_ID
	*	pair <ASN,ASN> 
	***/
	map <int, set <pair <unsigned int,unsigned int> > > link_indotti_nrs;
	
	/***
    *	Nodi senza route server
	*	contiene mapping tra AS_NUMBER e nodi di igraph:
	*	chiave => IXP_ID
	*	submap <ASN (key), nodo_igraph> 
	***/
	map <int, map <unsigned int, unsigned int> > nodi_indotti_nrs;
	
	/***
	*	ASN dei ruote server
	*	chiave => IXP_ID
	*	unsigned int => ASN del route Server
	***/
	map <int,unsigned int> route_server;	
	
	/***
	 *	membri di ogni IXP
	 *	chiave => IXP_ID
	 *	unsigned int => ASN
	 ***/
	map <int, set <unsigned int> > membri_ixp;
	
	/***
	 *	AS da escludere anche nel conteggio dei membri
	 *	la lista è organizzata a range
	 *	pair <ASN start, ASN end>
     *	se è un singolo AS: <ASi, ASi>
	 ***/
	set <pair <unsigned int, unsigned int> > AS_esclusi;
	
	/***
	 *	AS privati
	 *	la lista è organizzata a range
	 *	pair <ASN start, ASN end> 
	 ***/
	set <pair <unsigned int, unsigned int> > AS_privati;
	
	/***
     *	Informazioni sugli IXP
     *	key: ixp_id, value: informazioni
     ***/
    map < int, info_ixp > ixps;
    
    /***
    *	Struttura per salvare il grafo creato da nodi_indotti
    *	<IXP_ID, puntatore al grafo>
    ***/
    map <int, igraph_t> grafi;
    
    /***
    *	Struttura per salvare il grafo creato da nodi_indotti_nrs
    *	<IXP_ID, puntatore al grafo>
    ***/
    map <int, igraph_t> grafi_nrs;
    
    /***
    *	Struttura per salvare il grafo creato da nodi_indotti_nrs
    *	Crea una struttura a clique
    *	<IXP_ID, puntatore al grafo>
    ***/
    map <int, igraph_t> grafi_nrs_clique;
	
	/***
	 *	proprieta' strutturali dei sottografi indotti di ogni ixp
	 *	key:first = IXP_ID, 
	 *		second =	0 se il sottografo e' fatto considerando tutti i membri come AS normali
	 *					1 se il sottografo e' fatto togliendo il route server (RS)
	 *					2 se il sottografo e' fatto creando una full mesh fra gli AS collegati al RS
	 *	value: metriche associate al sottografo indotto
	 ***/
	map <pair <int, int>, metriche_ixp> proprieta_ixp;
     
    /***
     *	Struttura per salvare le metriche di ciascun AS
     *	key:first = ASN, 
	 *		second =	0 se i sottografi sono fatti considerando tutti i membri come AS normali
	 *					1 se i sottografi sono fatti togliendo il route server (RS)
	 *					2 se i sottografi sono fatti creando una full mesh fra gli AS collegati al RS
	 *	value: metriche dell'AS (member_presence, member_connectivity)
     ***/
    map <pair <unsigned int, int>, metriche_as > as_metric;
    
    /***
     *	proprieta strutturali degli IXP aggregate per continente
     *	key: first = continente (EU, NA, LA, OC, AS, AF),
     *		second =	0 se considerati i sottografi fatti con tutti i membri come AS normali
	 *					1 se considerati i sottografi fatti togliendo il route server (RS)
	 *					2 se considerati i sottografi fatti creando una clique fra gli AS peer del RS
     *	value:
     ***/
    map < pair < string, int >, metriche_agg > proprieta_ixp_agg;


/************************************************************************************************
 |                                                                                              |
 |                                                                                              |
 |                             Funzioni che caricano le strutture dati                          |
 |                                                                                              |
 |                                       (ixp_graph_load.cpp)                                   |
 |                                                                                              |
 |                                                                                              |
 ************************************************************************************************/
    
    /***
    *Legge le informazioni da ixp_info.txt e popola ixps
    *@return -1 errore lettura da file
    ***/
    int load_ixp_info ();

    /***
	 *	converte una stringa contenente un asn anche in notazione asdot o asdot+ in un numero naturale
	 *	@param ASN stringa da convertire
	 *	@param asn_num (out) variabile in cui viene restituito l'asn numerico
	 *	@return -1 in caso di errore (ASN ha un formato scorretto)
	 ***/
    int converti_as ( string ASN, unsigned int& asn_num );
    
    /***
     *	verifica che una stringa non rappresenti un numero naturale rappresentabile su piu' di 32 bit
     *	@param str stringa da verificare (deve contenere solo cifre)
     *	@return -1 se la stringa e' un numero naturale rappresentabile su piu' di 32 bit
     ***/
    int is_32bit ( string str );
	
	/***
	 *	Legge il grafo di internet e popola la struttura global
	 *	@return -1 in caso di errore
	 ***/
	int leggi_grafo();
	
	/***
	 *	Legge per ogni IXP il rispettivo Route Server e popola la struttura route_server
	 *	@return -1 in caso di errore
	 ***/
	int leggi_route_server();
	
	/***
	 *	Legge la lista dei membri degli ixp e popola la struttura membri_ixp
	 *	@return -1 in caso di errore
	 ***/
	int leggi_IXP();
    
	/***
	 *	Legge le liste degli AS speciali per popolare la struttura AS_esclusi o AS_privati
	 *	@param i 0 per popolare AS_esclusi, un qualsiasi altro valore per popolare AS_privati
	 *	@return -1 in caso di errore
	 ***/
	int leggi_AS_speciali ( int i );
	
	/***
	*	Popola la struttura link_indotti con le coppie derivanti dal grafo di internet che hanno un
	*	corrispettivo nei membri degli ixp
	***/
	void crea_link_indotti();
	
	/***
	*	Popola la struttura nodi_indotti con il mapping (che vuole igraph) degli ASN pubblici degli ixp
	***/
	void crea_nodi_indotti();
	
	/***
	 *	popola la struttura global_nrs togliendo dal grafo di Internet (global) i link fra un membro 
	 *	di un IXP e il route server dello stesso IXP
	 ***/
	void crea_global_nrs ();
	
	/***
	 *	popola la struttura global_nrs_clique
	 ***/
	void crea_global_nrs_clique ( );
	
	/***
	 *	verifica se due AS sono l'uno route server di un IXP e l'altro membro dello stesso IXP
	 *	@param rs AS Number del presunto route server
	 *	@param as AS Number dell'AS
	 *	@return true se as e' membro di un IXP di cui rs e' route server, false altrimenti
	 ***/
	bool are_rs_and_member ( unsigned int rs, unsigned int as );
	
	/***
	 *	verifica se due as sono membri normali (non rs) di uno stesso IXP
	 *	@param as1 AS Number del primo AS
	 *	@param as1 AS Number del secondo AS
	 *	@return true se as1 e as2 sono membri normali (non rs) di uno stesso IXP, false altrimenti
	 ***/
	bool are_member_and_member ( unsigned int as1, unsigned int as2 );
	
	/***
	 *	Crea il grafo di Intenet
	 *	@param link (in) variabile contenente i link da creare nel grafo
	 *	@param graph (out) grafo su cui salvare il risultato
	 *	@param mapping (out) varibile in cui salvare il mapping fra ASN e id del nodo igraph
	 ***/
	int create_global_graph ( const set < pair < unsigned int, unsigned int > >& link, igraph_t& graph, 
								map < unsigned int, unsigned int >& mapping );
	
	/***
    *	Popola la grafi_nrs_clique
    *	@param graph grafo su cui salvare il risultato
    ***/
        
    void crea_grafi_clique (map<int,igraph_t>& graph);
	
	/***
	 *	crea i sottografi indotti di ogni ixp. Restituisce una map (ixp_id, sottografo)
	 *	@param link link indotti da utilizzare
	 *	@param nodi nodi indotti da utilizzare
	 *	@param graph grafo su cui salvare il risultato
	 ***/
    void crea_sottografi( map <int, set <pair <unsigned int,unsigned int> > > & link,
                map <int, map <unsigned int, unsigned int> > & nodi, map<int,igraph_t>& graph );
                
                
/************************************************************************************************
 |                                                                                              |
 |                                                                                              |
 |                             Funzioni che calcolano le metriche dei grafi                     |
 |                                                                                              |
 |                                      (ixp_graph_metric.cpp)                                  |
 |                                                                                              |
 |                                                                                              |
 ************************************************************************************************/
	
	/***
	 *	calcola alcune metriche associate al degree
	 *	@param g (in) puntatore al grafo da analizzare
	 *	@param m (in) variabile contenente il mapping fra ASN e nodi igraph
	 *	@param pm (out) variabile in cui salvare il numero di membri con almeno 1 peering
	 *	@param md (out) variabile in cui salvare il degree massimo e gli asn corrispondenti
	 *	@param v (out) variabile in cui salvare la somma dei degree
	 *	@param t (in) indica di che tipo e' il grafo g (serve per riempire il secondo valore della 
	 *					chiave della map as_metric)
	 *	@param dg (out) variabile in cui salvare la pmf del degree
	 *	@param ccdf_dg (out) variabile in cui salvare la ccdf del degree
	 *	@return -1 in caso di errore
	 ***/
	int degree_metrics ( igraph_t* g, const map<unsigned int, unsigned int >& m, unsigned int& pm,
							pair<unsigned int, set<unsigned int> >& md, unsigned int& v, int t, map<unsigned int, float>& dg, map<unsigned int, float>& ccdf_dg );

	/***
	 *	calcola varie metriche di un ixp che prevedono la lettura del grafo di Internet
	 *	@param ixp_id (in) id dell'ixp da analizzare
	 *	@param g (in) puntatore al sottografo da analizzare
	 *	@param rs (in) se 0 significa che il route server deve essere considerato come membro semplice,
	 *					se 1 significa che non deve essere considerato neanche come non membro, 
	 *					se 2 significa che devo considerare una full mesh fra i peer del rs
	 *	@param m (in) variabile contenente i membri dell'ixp (ASN e id del nodo igraph)
	 *	@param met (in/out) struttura contenente numero di membri con ASN pubblico (public_members) 
	 *						e numero di link (peering) del sottografo indotto sull'ixp, e in cui 
	 *						salvare i risultati (edges_cut, conductance, cut_ratio, norm_cut)
	 *	@param edge_ext_as (out) variabile in cui viene restituito per ogni AS membro dell'IXP (key)
	 *								il numero di peering con non membri dell'IXP (value)
	 ***/							
	int internet_metrics ( int ixp_id, igraph_t* g, int rs, const map<unsigned int, unsigned int >& m, 
							metriche_ixp& met, map < unsigned int, unsigned int >& edge_ext_as );

	/***
	*	Calcola le metriche relative ai link per ogni IXP
	*	@param met (out) metrica su cui salvare il risultato
	*	@param ixp_id (in) id dell'ixp in esame
	*	@param graph (in) puntatore al grafo da analizzare
	***/
	int link_metrics(metriche_ixp &met, int ixp_id, igraph_t *graph);
	
	/***
	 *	calcola le metriche di odf e embeddedness dei nodi del sottografo
	 *	@param g (in) puntatore al grafo da analizzare
	 *	@param m (in) variabile contenente il mapping fra ASN e nodi igraph
	 *	@param edge_ext_as (in) numero di peering con non membri dell'IXP (value) 
	 *							per ogni AS membro dell'IXP (key)
	 *	@param met (out) struttura in cui salvare i risultati
	 *	@return -1 in caso di errore
	 ***/
	int odf_embed_metrics ( igraph_t* g, map<unsigned int, unsigned int >& m, 
								const map < unsigned int, unsigned int >& edge_ext_as, 
								metriche_ixp& met );
	
	/***
	 *	calcola le metriche di shell index di un sottografo indotto
	 *	@param g (in) puntatore al grafo da analizzare
	 *	@param avg (out) variabile in cui viene restituito lo shell index medio
	 *	@param max (out) variabile in cui viene restituito lo shell index massimo
	 *	@param min (out) variabile in cui viene restituito lo shell index minimo
	 *	@param pmf (out) variabile in cui viene restituito per ogni valore di shell index (key)
	 *						la frazione di nodi che ha tale valore (value)
	 *	@return -1 in caso di errore
	 ***/
	int shell_index_metrics ( igraph_t* g, float& avg, unsigned int& max, unsigned int& min,
								 map<unsigned int, float >& pmf);
	
	/***
	 *	calcola la ccdf a partire dalla pmf di una variabile aleatoria
	 *	@tparam va_type tipo dei valori che puo' assumere la variabile aleatoria
	 *	@param pmf (in) puntatore alla struttura contenente la pmf della v.a.
	 *	@param ccdf (out) variabile in cui viene restituita la ccdf della v.a.
	 ***/
	template < class va_type >
	void pmf_to_ccdf ( const map < va_type, float >* pmf, map < va_type, float >& ccdf );
	
	/***
	 *	inizializza una entry della map proprieta_ixp_agg
	 *	@param key_prop_agg puntatore alla chiave della entry da inizializzare
	 *	@param metriche puntatore alla struttura contenente i valori di inizializzazione delle metriche
	 ***/
	void init_proprieta_agg ( const pair < string, int >* key_prop_agg, const metriche_ixp* metriche );
	
	/***
	 *	aggiorna una entry della map proprieta_ixp_agg sommandovi nuovi valori
	 *	@param key_prop_agg puntatore alla chiave della entry da aggiornare
	 *	@param metriche puntatore alla struttura contenente i valori da sommare
	 ***/
	void sum_proprieta_agg ( const pair < string, int >* key_prop_agg, const metriche_ixp* metriche );
	
	/***
	 *	calcola le medie finali delle metriche contenute in proprieta_ixp_agg
	 ***/
	void avg_proprieta_agg ();
	 


/************************************************************************************************
 |                                                                                              |
 |                                                                                              |
 |                                    Funzioni per il debug                                     |
 |                                                                                              |
 |                                    (ixp_graph_print.cpp)                                     |
 |                                                                                              |
 |                                                                                              |
 ************************************************************************************************/
	
	/***
    *	Stampa a video il contenuto di membri_ixp
    ***/
    void debug_membri_ixp();
    
    /***
     *	debug: stampa il contenuto della variabile nodi_indotti
     ***/
    void stampa_nodi_indotti();
	
	/***
	 *	debug: stampa il contenuto delle variabili contenenti AS esclusi o AS privati
	 *	@param i 0 per stampare AS_esclusi, un qualsiasi altro valore per stampare AS_privati
	 ***/
	void stampa_AS_speciali ( int i );
	
	/***
	 *	debug: stampa il contenuto della variabile link_indotti
	 ***/
	void stampa_link_indotti ( );
	
	/***
	 *	debug: stampa il contenuto della variabile route_server
	 ***/
	void debug_route_server();
	
	/***
	 *	stampa il contenuto di una varibile di tipo set < pair < unsigned int, unsigned int > >
	 *	@param msg messaggio iniziale da stampare
	 *	@param var variabile di cui stampare il contenuto
	 ***/
	void stampa_set_di_pair_uint_uint ( const char* msg, 
										const set < pair < unsigned int, unsigned int > >& var );
	

public:


	/***
     *	Popola le strutture leggendo da file
	 ***/
    ixp_graph();
    
    /***
    *	Popola le strutture link_indotti(_nrs) e nodi_indotti(_nrs),
    *	grafi, grafi_nrs e grafi_nrs_clique
	***/
    void crea_grafi();
    
    
    /***
	 *	calcola le proprieta' strutturali dei sottografi indotti popolando la variabile proprieta_ixp
	 *	@param i se 0 considera grafi, se 1 considera grafi_nrs, se 2 considera grafi_nrs_clique, 
	 *				altrimenti considera grafi
	 *	@return -1 in caso di errore
	 ***/
	int calcola_metriche ( int i );
	
	/***
	 *	calcola le metriche degli IXP aggregate per continente
	 ***/
	void calcola_metriche_agg ();
	
	
	/***
	 *	stampa il contenuto della variabile proprieta_ixp
	 ***/
	void stampa_proprieta_ixp ();
	
	/***
	 *	stampa le metriche di ogni asn che saranno contenute in as_metric          
     ***/   
    void stampa_metriche_asn();
    
    /***
	 *	stampa il contenuto della variabile proprieta_ixp_agg
	 ***/
	void stampa_proprieta_aggregate ();
	
	/***
	 *	stampa le metriche in un formato utile a gnuplot
	 *	@param type_graph se 0 considera grafi, se 1 considera grafi_nrs, se 2 considera grafi_nrs_clique
	 *	@param id_ixp[]	vettore con gli id degli ixp da stampare
	 *	@param num_ixp numero di ixp da stampare		
	 ***/
	void stampa_proprieta_ixp_gnuplot (int id_ixp[], int num_ixp, int type_graph);
	
	/***
	 *	stampa le metriche aggregate in un formato untile a gnuplot
	 *	@param type_graph	se 0 considerati i sottografi fatti con tutti i membri come AS normali,
	 *						se 1 considerati i sottografi fatti togliendo il route server (RS),
	 *						se 2 considerati i sottografi fatti creando una clique fra gli AS peer del RS
	 *	@param file_out path del file di output
	 ***/
	void stampa_prop_ixp_agg_gnuplot ( int type_graph, const char* file_out );
	
	/***
	 *	stampa le proprieta' degli AS in un formato utile a gnuplot - NON USATA
	 *	@param type_graph	se 0 considerati i sottografi fatti con tutti i membri come AS normali,
	 *						se 1 considerati i sottografi fatti togliendo il route server (RS),
	 *						se 2 considerati i sottografi fatti creando una clique fra gli AS peer del RS
	 *	@param file_out path del file di output
	 ***/
	//void stampa_proprieta_as_gnuplot ( int type_graph, const char* file_out );
	
	/***
	* stampa le shell_index_pmf in formato utile per gnuplot su file <shind_base>_<type_graph>_<ixp_id>.txt
	* @param type_graph	se 0 considerati i sottografi fatti con tutti i membri come AS normali,
	*					se 1 considerati i sottografi fatti togliendo il route server (RS),
	*					se 2 considerati i sottografi fatti creando una clique fra gli AS peer del RS
	* @param ixp_id ID dell'ixp per cui fare la stampa
	***/
	//void stampa_shind_pmf(int ixp_id, int type_graph);
	
	/***
	 *	stampa la shell index ccdf di un IXP in formato utile per gnuplot
	 *	@param ixp_id id dell'ixp di cui stampare la ccdf
	 *	@param type_graph	se 0 considerati i sottografi fatti con tutti i membri come AS normali,
	 *						se 1 considerati i sottografi fatti togliendo il route server (RS),
	 *						se 2 considerati i sottografi fatti creando una clique fra gli AS peer del RS
	 *	@param file_out path base del file di output (il nome del file su cui effettivamente sara' 
	 *					stampato l'output sara' <file_out>_<ixp_id>_<type_graph>.txt)
	 ***/
	void stampa_shell_index_ccdf ( int ixp_id, int type_graph, const char* file_out );
	/***
	 *	stampa il degree ccdf di un IXP in formato utile per gnuplot
	 *	@param ixp_id id dell'ixp di cui stampare la ccdf
	 *	@param type_graph	se 0 considerati i sottografi fatti con tutti i membri come AS normali,
	 *						se 1 considerati i sottografi fatti togliendo il route server (RS),
	 *						se 2 considerati i sottografi fatti creando una clique fra gli AS peer del RS
	 *	@param file_out path base del file di output (il nome del file su cui effettivamente sara' 
	 *					stampato l'output sara' <file_out>_<ixp_id>_<type_graph>.txt)
	 ***/
	void stampa_degree_ccdf ( int ixp_id, int type_graph, const char* file_out );
	/***
	 *	stampa la shell index probability mass function di un aggregato di IXP
	 *	@param continent continente che identifica l'aggregato
	 *	@param type_graph	se 0 considerati i sottografi fatti con tutti i membri come AS normali,
	 *						se 1 considerati i sottografi fatti togliendo il route server (RS),
	 *						se 2 considerati i sottografi fatti creando una clique fra gli AS peer del RS
	 *	@param file_out path base del file di output (il nome del file su cui effettivamente sara' 
	 *					stampato l'output sara' <file_out>_<continent>_<type_graph>.txt)
	 ***/
	//void stampa_shell_index_pmf ( string continent, int type_graph, const char* file_out );
	
	/***
	 *	stampa la shell index ccdf di un aggregato di IXP in formato utile per gnuplot
	 *	@param continent continente che identifica l'aggregato
	 *	@param type_graph	se 0 considerati i sottografi fatti con tutti i membri come AS normali,
	 *						se 1 considerati i sottografi fatti togliendo il route server (RS),
	 *						se 2 considerati i sottografi fatti creando una clique fra gli AS peer del RS
	 *	@param file_out path base del file di output (il nome del file su cui effettivamente sara' 
	 *					stampato l'output sara' <file_out>_<continent>_<type_graph>.txt)
	 ***/
	void stampa_shell_index_ccdf ( string continent, int type_graph, const char* file_out );
	
	/***
	 *	stampa la link density ccdf di un aggregato di IXP in formato utile per gnuplot
	 *	@param continent continente che identifica l'aggregato
	 *	@param type_graph	se 0 considerati i sottografi fatti con tutti i membri come AS normali,
	 *						se 1 considerati i sottografi fatti togliendo il route server (RS),
	 *						se 2 considerati i sottografi fatti creando una clique fra gli AS peer del RS
	 *	@param file_out path base del file di output (il nome del file su cui effettivamente sara' 
	 *					stampato l'output sara' <file_out>_<continent>_<type_graph>.txt)
	 ***/
	void stampa_link_density_ccdf ( string continent, int type_graph, const char* file_out );

	/***
	 *	stampa i global degree per verificare se siamo in presenza di una relazione customer provider
	 *	@param ixp	id ixp
	 *	@param file_out path del file di output
	 ***/
	void stampa_as_tear1_gnuplot(int ixp, const char* file_out);
	
	/***
	 *	PROVA: VALUTAZIONI GENERALI SULL'INTERO STUDIO DEGLI IXP OSSERVATI...
	 ***/      
	void valutazione_ixp();
	
    /***
	 *	stampa a video un errore dovuto al calcolo delle metriche
	 ***/
	void check_metrics();
	 /***
	 *	scrive per gnuplot un file con la metrica "public_members" di tutti gli ixp ordinata in ordine decrescente
	 ***/
    void ordina_members_gnuplot(int type_graph, const char* file_out);
	 /***
	 *	scrive per gnuplot un file con la metrica "peering" di tutti gli ixp ordinata in ordine decrescente
	 ***/
    void ordina_peering_gnuplot(int type_graph, const char* file_out);
    
     /***
	 *	scrive per gnuplot un file con la metrica "Member_presence" di tutti gli as ordinata in ordine decrescente
	 ***/
	 void ordina_as_members_gnuplot(const char* file_out);
	 /***
	 *	scrive per gnuplot un file con la metrica "Member_connectivity" di tutti gli as ordinata in ordine decrescente
	 ***/
	 void ordina_as_connectivity_gnuplot(const char* file_out);
	 /***
	 *	stampa il degree_globale ccdf  di un IXP in formato utile per gnuplot
	 *	@param ixp_id id dell'ixp di cui stampare la ccdf
	 *	@param type_graph	se 0 considerati i sottografi fatti con tutti i membri come AS normali,
	 *						se 1 considerati i sottografi fatti togliendo il route server (RS),
	 *						se 2 considerati i sottografi fatti creando una clique fra gli AS peer del RS
	 *	@param file_out path base del file di output (il nome del file su cui effettivamente sara' 
	 *					stampato l'output sara' <file_out>_<ixp_id>_<type_graph>.txt)
	 ***/
	 void stampa_globaldg_ccdf ( int ixp_id, int type_graph, const char* file_out );
	 
	 
};



#endif

